/**
 * This file is part of Wireless TransFer.
 *
 *   Wireless TransFer is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *	
 *   Wireless TransFer is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with Wireless TransFer.  If not, see <http://www.gnu.org/licenses/>.
 *
 *	 Copyright (C) 2011
 *   @author skalman
 */

package com.wirelesstransfer.server.ConnectedClients;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.Map.Entry;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import com.wirelesstransfer.AsyncTasks.UpdateStatusList;

/**
 * Handling all clients connected to the server
 *
 */

public final class ConnectedClientsHandler implements IConnectedClients {

	private static ConnectedClientsHandler instance;
	
	private Lock lock = new ReentrantLock();
	
	private UpdateStatusList updateStatusList;
	
	private int id;
	private final static int MIN = 1000;
	private final static int MAX = 8000;
	
	// Map ID, ConnectedClient.
	private volatile HashMap<String,ConnectedClient> clients = new HashMap<String,ConnectedClient>();

	private ConnectedClientsHandler(){
		Random random = new Random();
		id = MIN + random.nextInt(MAX);
	}
	
	public synchronized static ConnectedClientsHandler getInstance(){
		if(instance == null){
			instance = new ConnectedClientsHandler();
		}
		return instance;
	}
	
	public synchronized List<ConnectedClient> getConnectedClients() {
		lock.lock();
		List<ConnectedClient> cs = new ArrayList<ConnectedClient>();
		
		for(Entry<String, ConnectedClient> e : clients.entrySet()){
			cs.add(e.getValue());
		}
		lock.unlock();
		return cs;
	}

	public synchronized boolean addClient(ConnectedClient client) {
		lock.lock();
		boolean ret = clients.put(client.getId(), client) != null;
		String ip = client.getIP();
		updateStatusList = new UpdateStatusList();
		updateStatusList.execute(ip,ip);
		lock.unlock();
		return ret;
	}

	public synchronized boolean removeClient(ConnectedClient client) {
		lock.lock();
		boolean ret = clients.remove(client.getId()) != null;
		String ip = client.getIP();
		updateStatusList = new UpdateStatusList();
		updateStatusList.execute(ip,ip);
		lock.unlock();
		return ret;
	}
	
	public synchronized ConnectedClient getClientById(String id) {
		lock.lock();
		ConnectedClient client =  clients.get(id);
		lock.unlock();
		return client;
	}
	
	/**
	 * generates a unique id for a client for the server connection
	 * @return unique id
	 */
	public synchronized String generateId(){
		return String.valueOf(id++);
	}
}
